package game.leon.war.node.handler;

import com.google.protobuf.GeneratedMessage;
import game.leon.engine.net.codec.GateRawMessage;
import game.leon.war.defs.MessageConsts;
import game.leon.war.defs.Vo;
import game.leon.war.node.WarNode;
import game.leon.war.node.handler.letter.NodeLetter;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

/**
 * 注册各个消息的处理器和反序列化类型
 * User: bianpeng
 * Date: 12-1-31
 */
@Component
public class HandlerService {
    private Logger logger = Logger.getLogger(getClass());
    private HandlerSuite[] handlerMap;
    // builders
    private Builder idVoBuilder = new Builder() {
        @Override
        public GeneratedMessage.Builder builder() {
            return Vo.IdVO.newBuilder();
        }
    };
    // handlers
    @Autowired
    private CreateBattleHandler createBattleHandler;
    @Autowired
    private BattleTickHandler battleTickHandler;

    @PostConstruct
    public void init() {
        handlerMap = new HandlerSuite[MessageConsts.MAX];
        /// 注册处理器
        registerHandler(MessageConsts.BATTLE_CREATE, idVoBuilder, createBattleHandler);
        // 延时消息处理器
        registerHandler(MessageConsts.BATTLE_TICK, battleTickHandler);
    }
    @SuppressWarnings("unchecked")
    private void registerHandler(int message, Builder builder, Handler fun) {
        HandlerSuite suite = handlerMap[message];
        if (suite == null) {
            suite = new HandlerSuite(builder);
            handlerMap[message] = suite;
        }
        suite.add(fun);
    }
    @SuppressWarnings("unchecked")
    private void registerHandler(int message, Handler fun) {
        HandlerSuite suite = handlerMap[message];
        if (suite == null) {
            suite = new HandlerSuite(idVoBuilder);
            handlerMap[message] = suite;
        }
        suite.add(fun);
    }
    @Autowired
    private WarNode node;
    //
    // handle socket message
    //
    public void handle(GateRawMessage message) {
        HandlerSuite suite = handlerMap[message.getMessage()];
        if (suite == null) {
            logger.warn("message missing handler: " + message.getMessage());
            return;
        }
        GeneratedMessage result = suite.handle(message);
        if (result != null) {
            node.write(message.getUserId(), message.getMessage(), result);
        }
    }
    //
    // execute letter, server side delay message
    //
    public void handle(NodeLetter letter) {
        HandlerSuite suite = handlerMap[letter.getMessage()];
        if (suite == null) {
            logger.warn("letter miss handler: " + letter.getMessage());
            return;
        }
        suite.handle(letter);
    }
}
